<template>
  <div class="props-table">
    <div v-for="(value, key) in finalProps" :key="key" class="prop-item">
      <span class="label" v-if="value?.text">{{ value.text }}</span>
      <div class="prop-component">
        <component
          :is="value?.component"
          :[value.valueProp]="value.value"
          v-bind="value?.extraProps"
          v-on="value.events"
        >
          <template v-if="value.options">
            <component
              :is="value.subComponent"
              v-for="(option, k) in value.options"
              :key="k"
              :value="option.value"
            >
              <!-- {{ option.text }} -->
              <render-vnode :vNode="option.text" />
            </component>
          </template>
        </component>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, PropType, VNode } from "vue";
import { reduce } from "lodash";
import { AllComponentProps } from "fast-share-bricks";
import { TextComponentProps } from "../defaultProps";
import { PropsToForms, mapPropsToForms } from "../propsMap";
import RenderVnode from "./RenderVnode";
import ColorPicker from "./ColorPicker.vue";
import ImageProcesser from "./ImageProcesser.vue";
import ShadowPicker from "./ShadowPicker.vue";
import BackgroundProcesser from "./BackgroundProcesser.vue";

interface FormProps {
  component: string;
  subComponent?: string;
  value: string;
  extraProps?: { [key: string]: any };
  text?: string;
  options?: { text: string | VNode; value: any }[];
  valueProp: string;
  eventName: string;
  events: { [key: string]: (e: any) => void };
}
export default defineComponent({
  name: "props-table",
  props: {
    props: {
      type: Object as PropType<AllComponentProps>,
      // type: Object as PropType<any>,
      required: true,
    },
  },
  components: {
    RenderVnode,
    ColorPicker,
    ImageProcesser,
    ShadowPicker,
    BackgroundProcesser,
  },
  emits: ["change"],
  setup(props, { emit }) {
    const finalProps = computed(() => {
      return reduce(
        props.props,
        (result, value, key) => {
          const typeKey = key as keyof TextComponentProps; // 断言
          const item = mapPropsToForms[typeKey];
          if (item) {
            const {
              valueProp = "value",
              eventName = "change",
              initalTransform,
              afterTransform,
            } = item;
            const newItem: FormProps = {
              ...item,
              value: initalTransform ? initalTransform(value) : value,
              valueProp,
              eventName,
              events: {
                [eventName]: (e: any) => {
                  emit("change", {
                    key,
                    value: afterTransform ? afterTransform(e) : e,
                  });
                },
              },
            };
            result[typeKey] = newItem;
          }
          return result;
        },
        // {} as PropsToForms
        // {} as Required<PropsToForms> // 消除类型错误
        {} as { [key: string]: FormProps }
      );
    });
    return {
      finalProps,
    };
  },
});
</script>
<style lang="scss" scoped>
.props-table {
  .prop-item {
    display: flex;
    margin-bottom: 10px;
    align-items: center;
    &.no-text {
      display: inline-block;
      margin: 0 10px 0 0;
    }
  }
  .label {
    width: 28%;
  }
  .prop-component {
    width: 70%;
  }
  #item-fontWeight {
    margin-left: 28%;
  }
  .component-a-select .ant-select {
    width: 150px;
  }
  .prop-component {
    &.component-shadow-picker,
    &.component-background-processer,
    &.component-image-processer {
      width: 100%;
    }
  }
}
</style>
